package com.webex.ta.hydra.util;

import com.webex.ta.hydra.core.Command;
import com.webex.ta.hydra.core.KeywordRegistry;
import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.swing.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-8-25
 * Time: 14:57:58
 */
public class HydraUtils {

    private static String hydraDir;
    private static String hydraBin;
    private static String hydraTemplate;
    private static String hydraPlugin;
    private static String hydraTmp;

    private static Map<String, ImageIcon> images = new HashMap<String, ImageIcon>();

    public static void setHydraHome(String home) {
        hydraDir = home;
        hydraBin = hydraDir + File.separator + "bin";
        hydraTemplate = hydraDir + File.separator + "template";
        hydraPlugin = hydraDir + File.separator + "plugins";
        hydraTmp = hydraDir + File.separator + "tmp";
    }

    public static String getHydraHome() {
        return hydraDir;
    }

    public static String getHydraBinPath() {
        return hydraBin;
    }

    public static String getHydraTemplatePath() {
        return hydraTemplate;
    }

    public static String getHydraPluginPath() {
        return hydraPlugin;
    }

    public static String getHydraTempPath() {
        return hydraTmp;
    }

    public static Template getFreeMarkerTemplate(String name) {
        Configuration cfg = new Configuration();
        try {
            cfg.setDirectoryForTemplateLoading(new File(hydraTemplate));
            return cfg.getTemplate(name);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static ImageIcon getImage(String name) {
        ImageIcon icon = images.get(name);
        if (icon == null) {
            icon = new ImageIcon(HydraUtils.class.getClassLoader().getResource(
                    "com/webex/ta/hydra/images/" + name.trim()));
            images.put(name, icon);
        }
        return icon;
    }

    public static String[] getCorePaths() {
        String[] result = new String[1];
        result[0] = getHydraHome() + "/lib/hydra";
        return result;
    }

    public static boolean isController(String keyword) {
        return KeywordRegistry.getInstance().getControllerNames().contains(keyword);
    }

    public static boolean isController(Command cmd) {
        return isController(cmd.getKeyword());
    }

    public static boolean isProcessor(String keyword) {
        return KeywordRegistry.getInstance().getProcessorNames().contains(keyword);
    }

    public static boolean isProcessor(Command cmd) {
        return isProcessor(cmd.getKeyword());
    }

    public static boolean isAssertion(String keyword) {
        return KeywordRegistry.getInstance().getAssertionNames().contains(keyword);
    }

    public static boolean isAssertion(Command cmd) {
        return isAssertion(cmd.getKeyword());
    }

    public static boolean isAction(String keyword) {
        return KeywordRegistry.getInstance().getActionNames().contains(keyword);
    }

    public static boolean isAction(Command cmd) {
        return isAction(cmd.getKeyword());
    }

    public static boolean isMacro(String keyword) {
        return KeywordRegistry.getInstance().getMacroDefinition(keyword) != null;
    }

    public static boolean copyStream(int bufferSize, ProgressObserver progress,
                                     InputStream in, OutputStream out, boolean canStop)
            throws IOException {
        byte[] buffer = new byte[bufferSize];
        int n;
        int copied = 0;
        while (-1 != (n = in.read(buffer))) {
            out.write(buffer, 0, n);
            copied += n;
            if (progress != null)
                progress.setValue(copied);
            if (canStop && Thread.interrupted()) return false;
        }
        return true;
    }

    public static boolean copyStream(ProgressObserver progress,
                                     InputStream in, OutputStream out, boolean canStop)
            throws IOException {
        return copyStream(4096, progress, in, out, canStop);
    }

    public static void closeQuietly(InputStream is) {
        try {
            if (is != null) is.close();
        } catch (IOException e) {
            // ignore
        }
    }

    public static void closeQuietly(OutputStream os) {
        try {
            if (os != null) os.close();
        } catch (IOException e) {
            // ignore
        }
    }

    public static String printStackTraceToString(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }

    public static Icon getIconForKeyword(String kw) {
        Icon icon;
        if (HydraUtils.isController(kw)) {
            icon = HydraUtils.getImage("folder.gif");
        } else if (HydraUtils.isProcessor(kw)) {
            icon = HydraUtils.getImage("processor.gif");
        } else if (HydraUtils.isAction(kw)) {
            icon = HydraUtils.getImage("runtime.gif");
        } else if (HydraUtils.isMacro(kw)) {
            icon = HydraUtils.getImage("macro.gif");
        } else {
            icon = HydraUtils.getImage("unknown.gif");
        }

        return icon;
    }

    public static Icon getIconForCommand(Command cmd) {
        Icon icon;
        if (HydraUtils.isController(cmd)) {
            if (cmd.isExpanded())
                icon = HydraUtils.getImage("fldr_obj.gif");
            else
                icon = HydraUtils.getImage("folder.gif");
        } else if (HydraUtils.isProcessor(cmd)) {
            icon = HydraUtils.getImage("processor.gif");
        } else if (HydraUtils.isAction(cmd)) {
            icon = HydraUtils.getImage("runtime.gif");
        } else if (HydraUtils.isAssertion(cmd)) {
            icon = HydraUtils.getImage("assert.gif");
        } else if (HydraUtils.isMacro(cmd.getKeyword())) {
            icon = HydraUtils.getImage("macro.gif");
        } else {
            icon = HydraUtils.getImage("unknown.gif");
        }
        if (!cmd.isEnabled())
            icon = UIManager.getLookAndFeel().getDisabledSelectedIcon(null, icon);
        return icon;
    }
}
